﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace GIFT
{
    public partial class VentanaJerarquia : Form
    {
        //Constructor de la clase
        public VentanaJerarquia(String nombre, InterfazPrincipal vPrincipal)
        {
            this.controlJerarquia = new ControlJerarquia();
            this.modificado = false;
            this.Principal = vPrincipal;
            this.Nombre = nombre; //pone el nombre
            InitializeComponent();
            this.Name = Nombre;
            this.Text = Nombre;
            this.textBox_jerarquia_nombre.Text = Nombre;
            this.textBox_jerarquia_fecha_creacion.Text = DateTime.Now.ToString();
            this.textBox_jerarquia_actualizacion.Text = DateTime.Now.ToString();
        }

        ///Metodos set

        //Le da valor al campo correlativo
        public void setCorrelativo(String correlativo)
        {
            textBox_jerarquia_correlativo.Text = correlativo;
        }

        //Le da valor al campo nombre
        public void setNombre(String nombre)
        {
            textBox_jerarquia_nombre.Text = nombre;
        }

        //Le da valor al campo descripcion
        public void setDescripcion(String descripcion)
        {
            textBox_jerarquia_descripcion.Text = descripcion;
        }

        //Le da valor al campo fecha actualizacion
        public void setActualizacion(String fechaActualizacion)
        {
            textBox_jerarquia_actualizacion.Text = fechaActualizacion;
        }

        //Le da valor al campo fecha de creacion
        public void setCreacion(String fechaCreacion)
        {
            textBox_jerarquia_fecha_creacion.Text = fechaCreacion;
        }

        //Le da valor al campo numero de terminos
        public void setNumTerminos(String terminos)
        {
            textBox_jerarquia_Numero_terminos.Text = terminos;
        }

        //Le da valor al campo numero de niveles
        public void setNumNiveles(String niveles)
        {
            textBox_jerarquia_Numero_niveles.Text = niveles;
        }

        //Le da valor al campo nombre de termino
        public void setNombreTermino(String termino)
        {
            textBox_jerarquia_nombre_termino.Text = termino;
        }

        //Le da valor al campo ruta raiz
        public void setRutaRaiz(String ruta)
        {
            textBox_jerarquia_path.Text = ruta;
        }

        //Le da valor al campo descripcion al termino
        public void setDescripcionTermino(String descripcion)
        {
            textBox_jerarquia_descripcion_termino.Text = descripcion;
        }

        //Le da valor al campo version al termino
        public void setVersionTermino(String version)
        {
            textBox_jerarquia_version_termino.Text = version;
        }

        //Le da valor al campo lista principal de categorias
        public void setListaPrincipalCategorias(String categoria)
        {
            comboBox_jerarquia_lista_principal_categorias.Text = categoria;
        }

        //Le da valor al campo lista principal de niveles
        public void setListaPrincipalNiveles(String nivel)
        {
            ComboBox_jerarquia_lista_principal_niveles.Text = nivel;
        }

        //Le da valor al campo lista categorias de termino
        public void setListaCategoriaTermino(String categoria)
        {
            comboBox_jerarquia_lista_categoria_termino.Text = categoria;
        }

        //Pone el indice que recibe en el campo lista categorias de termino
        public void setListaCategoriaTermino(int indice)
        {
            comboBox_jerarquia_lista_categoria_termino.SelectedIndex = indice;
        }

        //Le da valor al campo lista niveles de termino
        public void setListaNivelTermino(String nivel)
        {
            comboBox_jerarquia_lista_nivel_termino.Text = nivel;
        }

        //Pone el indice que recibe en el campo lista niveles de termino
        public void setListaNivelTermino(int indice)
        {
            comboBox_jerarquia_lista_nivel_termino.SelectedIndex = indice;
        }

        //Le da valor al campo numero de nivel
        public void setNumeroNivel(String numNivel)
        {
            ComboBox_jerarquia_numero_nivel.Text = numNivel;
        }

        //Pone el indice que recibe en el campo numero de nivel
        public void setNumeroNivel(int indice)
        {
            ComboBox_jerarquia_numero_nivel.SelectedIndex = indice;
        }

        //Le da valor al campo buscar termino
        public void setBuscarTermino(String valor)
        {
            textBox_jerarquia_buscar_termino.Text = valor;
        }

        //Cambia el valor del check de Nombre por nivel
        public void setNombrePorNivel(bool valor)
        {
            checkBox_jerarquia_nombre_por_nivel.Checked = valor;
        }

        //Cambia el valor del check de con niveles
        public void setConNiveles(bool valor)
        {
            checkBox_jerarquia_con_niveles.Checked = valor;
        }

        //Cambia el valor del check de con categorias
        public void setConCategorias(bool valor)
        {
            checkBox_jerarquia_con_categorias.Checked = valor;
        }

        //Cambia el valor del check de con version
        public void setConVersion(bool valor)
        {
            checkBox_jerarquia_con_version.Checked = valor;
        }

        //Llena la lista desplegable con los niveles
        public void llenarListaPrincipalNiveles(ArrayList niveles)
        {
            for (int i = 0; i < niveles.Count; ++i)
            {
                ComboBox_jerarquia_lista_principal_niveles.Items.Add(niveles[i].ToString());
            }
        }

        //Limpia la lista desplegable de los niveles
        public void LimpiarListaPrincipalNiveles()
        {
            ComboBox_jerarquia_lista_principal_niveles.Items.Clear();
        }

        //Llena la lista desplegable con los niveles de los terminos
        public void llenarListaNivelesTermino(ArrayList niveles)
        {
            for (int i = 0; i < niveles.Count; ++i)
            {
                comboBox_jerarquia_lista_nivel_termino.Items.Add(niveles[i].ToString());
            }
        }

        //Limpia la lista desplegable de los niveles de los terminos
        public void LimpiarListaNivelesTermino()
        {
            comboBox_jerarquia_lista_nivel_termino.Items.Clear();
        }

        //Llena la lista desplegable con las categorias
        public void llenarListaPrincipalCategorias(ArrayList categorias)
        {
            for (int i = 0; i < categorias.Count; ++i)
            {
                comboBox_jerarquia_lista_principal_categorias.Items.Add(categorias[i].ToString());
            }
        }

        //Limpia la lista desplegable de las categorias
        public void LimpiarListaPrincipalCategorias()
        {
            comboBox_jerarquia_lista_principal_categorias.Items.Clear();
        }

        //Llena la lista desplegable con las categorias de termino
        public void llenarListaCategoriasTermino(ArrayList categorias)
        {
            for (int i = 0; i < categorias.Count; ++i)
            {
                comboBox_jerarquia_lista_categoria_termino.Items.Add(categorias[i].ToString());
            }
        }

        //Limpia la lista desplegable de las categorias de termino
        public void LimpiarListaCategoriasTermino()
        {
            comboBox_jerarquia_lista_categoria_termino.Items.Clear();
        }

        //Llena la lista desplegable con la cantidadd de niveles
        public void llenarNumeroNiveles(int canNiveles)
        {
            for (int i = 1; i <= canNiveles; ++i)
            {
                ComboBox_jerarquia_numero_nivel.Items.Add(i.ToString());
            }
        }

        //Limpia la lista desplegable de numero de niveles
        public void LimpiarNumeroNiveles()
        {
            ComboBox_jerarquia_numero_nivel.Items.Clear();
        }


        //Cambia la habilitacion del boton guardar
        public void habilitacionBotonGuardar(bool habilitacion)
        {
            botonGuardarJerarquia.Enabled = habilitacion;
        }

        //Cambia la habilitacion del boton agregar termino
        public void habilitacionBotonAgregarTermino(bool habilitacion)
        {
            button_jerarquia_agregar_termino.Enabled = habilitacion;
        }

        //Cambia la habilitacion del boton modificar termino
        public void habilitacionBotonModificarTermino(bool habilitacion)
        {
            button_jerarquia_modificar_termino.Enabled = habilitacion;
        }

        //Cambia la habilitacion del boton elimiar termino
        public void habilitacionBotonElimiarTermino(bool habilitacion)
        {
            button_jerarquia_eliminar_termino.Enabled = habilitacion;
        }

        //Llena el arbol con los datos que recibe como parametro
        public void llenarArbol(ArrayList NombreNodos, ArrayList idNodos, ArrayList idPadre)
        {
            ArrayList nodos = new ArrayList();//Guarda los nodos creados
            for (int i = 0; i < NombreNodos.Count; ++i)
            {
                TreeNode tnode = new TreeNode(NombreNodos[i].ToString());//Crea los nodos con el nombre
                tnode.ContextMenuStrip = contextMenuStrip_clickDerecho_arbol_jerarquia; //Agrega el menuStrip para el click derecho
                nodos.Add(tnode);//Los guarda en la lista
            }
            //Primero llena las raices
            for (int i = 0; i < NombreNodos.Count; ++i)
            {
                if ((String)idPadre[i] == "")//Si el padre es raiz
                {
                    treeView_jerarquia.Nodes.Add((TreeNode)nodos[i]);
                }
            }
            //Llena el resto del arbol
            for (int i = 0; i < NombreNodos.Count; ++i)
            {
                for (int j = 0; j < NombreNodos.Count; ++j)
                {
                    if ((String)idNodos[i] == (String)idPadre[j])
                    {
                        ((TreeNode)nodos[i]).Nodes.Add((TreeNode)nodos[j]);
                    }
                }
            }
        }


        //Metodos Get

        //Retorna el valor del campo correlativo
        public String getCorrelativo()
        {
            return textBox_jerarquia_correlativo.Text;
        }

        //Retorna el  valor del campo nombre
        public String getNombre()
        {
            return Nombre;
        }

        //Retorna el  valor del campo descripcion
        public String getDescripcion()
        {
            return textBox_jerarquia_descripcion.Text;
        }

        //Retorna el  valor del campo fecha actualizacion
        public String getActualizacion()
        {
            return textBox_jerarquia_actualizacion.Text;
        }

        //Retorna el valor del campo fecha de creacion
        public String getCreacion()
        {
            return textBox_jerarquia_fecha_creacion.Text;
        }

        //Retorna el valor del campo numero de terminos
        public String getNumTerminos()
        {
            return textBox_jerarquia_Numero_terminos.Text;
        }

        //Retorna el valor del campo numero de niveles
        public String getNumNiveles()
        {
            return textBox_jerarquia_Numero_niveles.Text;
        }

        //Retorna el valor del campo nombre de termino
        public String getNombreTermino()
        {
            return textBox_jerarquia_nombre_termino.Text;
        }

        //Retorna el valor del campo ruta raiz
        public String getRutaRaiz()
        {
            return textBox_jerarquia_path.Text;
        }

        //Retorna el valor del campo descripcion del termino
        public String getDescripcionTermino()
        {
            return textBox_jerarquia_descripcion_termino.Text;
        }

        //Retorna el valor del campo version del termino
        public String getVersionTermino()
        {
            return textBox_jerarquia_version_termino.Text;
        }

        //Retorna el valor actual del campo lista principal de categorias
        public String getListaPrincipalCategorias()
        {
            return comboBox_jerarquia_lista_principal_categorias.Text;
        }

        //Retorna el valor del campo lista principal de niveles
        public String getListaPrincipalNiveles()
        {
            return ComboBox_jerarquia_lista_principal_niveles.Text;
        }

        //Retorna el valor del campo lista categorias de termino
        public String getListaCategoriaTermino()
        {
            return comboBox_jerarquia_lista_categoria_termino.Text;
        }

        //Retorna el valor del campo lista niveles de termino
        public String getListaNivelTermino()
        {
            return comboBox_jerarquia_lista_nivel_termino.Text;
        }

        //Retorna el valor del campo numero de nivel
        public String getNumeroNivel()
        {
            return ComboBox_jerarquia_numero_nivel.Text;
        }

        //Retorna el valor del campo buscar termino
        public String getBuscarTermino()
        {
            return textBox_jerarquia_buscar_termino.Text;
        }

        //Retorna el valor del check de Nombre por nivel
        public bool getNombrePorNivel()
        {
            return checkBox_jerarquia_nombre_por_nivel.Checked;
        }

        //Retorna el valor del check de con niveles
        public bool getConNiveles()
        {
            return checkBox_jerarquia_con_niveles.Checked;
        }

        //Retorna el valor del check de con categorias
        public bool getConCategorias()
        {
            return checkBox_jerarquia_con_categorias.Checked;
        }

        //Retorna el valor del check de con version
        public bool getConVersion()
        {
            return checkBox_jerarquia_con_version.Checked;
        }

        //Retorna el arbol jerarquico
        public TreeView getArbolJerarquico()
        {
            return treeView_jerarquia;
        }

        //Captura el evento del check en con version
        private void check_con_version(object sender, EventArgs e)
        {
            if (checkBox_jerarquia_con_version.Checked)//Si se marco
            {
                textBox_jerarquia_version_termino.Enabled = true;
            }
            else //Si se desmarco
            {
                textBox_jerarquia_version_termino.Enabled = false;
                deshabiliatarVersionTermino();//Pone los atributos como null en su version
            }
            seHicieronCambios(null, null);//Avisa que se realizaron cambios
        }

        //Captura el evento del check en categorias
        private void checkBox_jerarquia_con_categorias_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox_jerarquia_con_categorias.Checked) //si se desea marcar 
            {
                comboBox_jerarquia_lista_principal_categorias.Enabled = true; //habilita los campos
                comboBox_jerarquia_lista_categoria_termino.Enabled = true;
                if (Principal.estaAbierta(Nombre))
                {
                    establecerCategoriaDefecto();//Pone la categoria por defecto
                }
            }
            else //si se desea desmarcar
            {
                comboBox_jerarquia_lista_principal_categorias.Enabled = false; //deshabilita los campos
                comboBox_jerarquia_lista_categoria_termino.Enabled = false;
                quitarCategoriasJerarquia();//Manda a quitar las categorias
            }
            seHicieronCambios(null, null);//Avisa que se realizaron cambios
        }

        //Captura el evento del check en niveles
        private void checkBox_jerarquia_con_niveles_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox_jerarquia_con_niveles.Checked)//Si se marca con niveles
            {
                checkBox_jerarquia_nombre_por_nivel.Enabled = true;
                ComboBox_jerarquia_numero_nivel.Enabled = true;
                if (Principal.estaAbierta(Nombre))
                {
                    establecerNivelDefecto();//Pone la categoria por defecto
                }
            }
            else //Si se desmarca con niveles
            {
                checkBox_jerarquia_nombre_por_nivel.Enabled = false;
                checkBox_jerarquia_nombre_por_nivel.Checked = false;
                ComboBox_jerarquia_numero_nivel.Enabled = false;
                ComboBox_jerarquia_lista_principal_niveles.Enabled = false;
                ComboBox_jerarquia_lista_principal_niveles.SelectedIndex = 0;
                comboBox_jerarquia_lista_nivel_termino.Enabled = false;
                quitarNivelesJerarquia();//Quita los niveles de la jerarquia
            }
            seHicieronCambios(null, null);//Avisa que se realizaron cambios
        }

        //Captura el evento del check en nombre nivel
        private void checkBox_jerarquia_nombre_por_nivel_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox_jerarquia_nombre_por_nivel.Checked) //si tiene nombre nivel 
            {
                ComboBox_jerarquia_lista_principal_niveles.Enabled = true;
                ComboBox_jerarquia_lista_principal_niveles.SelectedIndex = 0;
                comboBox_jerarquia_lista_nivel_termino.Enabled = true;
            }
            else//si no tiene nombre nivel 
            {
                ComboBox_jerarquia_lista_principal_niveles.Enabled = false;
                ComboBox_jerarquia_lista_principal_niveles.SelectedIndex = 0;
                comboBox_jerarquia_lista_nivel_termino.Enabled = false;
            }
            if (Principal.estaAbierta(Nombre))
            {
                establecerNivelDefecto();//Pone la categoria por defecto
            }
        }

        //Captura el evento del keyPress el campo de nombre de termino
        private void keyPress_campo_nombre_termino(object sender, KeyPressEventArgs e)
        {
            button_jerarquia_agregar_termino.Enabled = true;
            button_jerarquia_eliminar_termino.Enabled = false;
            button_jerarquia_modificar_termino.Enabled = false;
        }

        //Captura el evento de la seleccion de un nodo
        private void nodoSeleccionado(object sender, TreeNodeMouseClickEventArgs e)
        {
            (e.Node.TreeView).SelectedNode = e.Node; //Pone el nodo como el seleccionado
            cargarTermino(e.Node.Text);
        }

        //Captura el evento del click en buscar termino
        private void buscarTermino_Click(object sender, EventArgs e)
        {
            buscarTermino();
            button_jerarquia_buscar_termino.Enabled = false;
        }

        //Captura el evento del enter en el campo de buscar termino
        private void enterBuscarTermino(object sender, System.Windows.Forms.KeyPressEventArgs e)
        {
            button_jerarquia_buscar_termino.Enabled = true;
            if (e.KeyChar == (char)13)
            {
                buscarTermino();
                button_jerarquia_buscar_termino.Enabled = false;
            }
        }

        //Captura el evento de modificar un termino
        private void Click_modificar_termino(object sender, EventArgs e)
        {
            modificarTermino();
            button_jerarquia_modificar_termino.Enabled = false;
        }

        //Captura el evento cuando se cambia la lista de categorias
        private void cambioListaCategorias(object sender, EventArgs e)
        {
            if (Principal.estaAbierta(Nombre))
            {
                llenarListaCategoriasDeTermino();
                seHicieronCambios(null,null);
            }
        }

        //Captura el evento cuando se cambia la lista de niveles
        private void cambioListaNiveles(object sender, EventArgs e)
        {
            if (Principal.estaAbierta(Nombre))
            {
                llenarListaNivelesDeTermino();
                seHicieronCambios(null,null);
            }
        }

        //Captura el evento del click en el boton agregar termino
        private void clickBotonAgregarTermino(object sender, EventArgs e)
        {
            if (!agregarTermino())
            {
                MessageBox.Show("El nombre ya existe!"); //Informa
            }
            //Limpia los campos
            textBox_jerarquia_nombre_termino.Text = textBox_jerarquia_descripcion_termino.Text = textBox_jerarquia_version_termino.Text = "";
            ComboBox_jerarquia_numero_nivel.SelectedIndex = -1;
            comboBox_jerarquia_lista_categoria_termino.SelectedIndex = -1;
            comboBox_jerarquia_lista_nivel_termino.SelectedIndex = -1;
        }

        //Captura el evento del click en el boton eliminar termino
        private void clickBotonEliminarTermino(object sender, EventArgs e)
        {
            //confirma el borrado
            DialogResult dr = MessageBox.Show("Está seguro que desea borrar el termino?",
                      "Borrar Termino", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            switch (dr)
            {
                case DialogResult.Yes: //en caso de que desee borrarlo

                    eliminarTermino();//manda a eliminar el termino
                    //Limpia los campos
                    textBox_jerarquia_nombre_termino.Text = textBox_jerarquia_descripcion_termino.Text = textBox_jerarquia_version_termino.Text = "";
                    ComboBox_jerarquia_numero_nivel.SelectedIndex = -1;
                    comboBox_jerarquia_lista_categoria_termino.SelectedIndex = -1;
                    comboBox_jerarquia_lista_nivel_termino.SelectedIndex = -1;
                    button_jerarquia_eliminar_termino.Enabled = false;
                    break;
                case DialogResult.No: break;
            }
        }

        //Captura el evento del click en agregar hijo en click derecho del arbol
        private void agregarHijo_arbol_jerarquia_Click(object sender, EventArgs e)
        {
            TreeNode padre = treeView_jerarquia.SelectedNode; //Busca al padre 
            //Va a agregar al treeView
            TreeNode tnode = new TreeNode("nuevo");
            tnode.ContextMenuStrip = contextMenuStrip_clickDerecho_arbol_jerarquia; //Agrega el menuStrip para el click derecho
            padre.Nodes.Add(tnode);
            treeView_jerarquia.ExpandAll();
            tnode.BeginEdit(); //Empieza la edicion de la etiqueta
            textBox_jerarquia_nombre_termino.Text = "";
        }

        //Captura el evento de editar la etiqueta del nodo
        private void etiqueta_editada(object sender, NodeLabelEditEventArgs e)
        {
            if (textBox_jerarquia_nombre_termino.Text != "")//Si es edicion del nombre de termino
            {
                if (!editarNombreTermino(e.Label, textBox_jerarquia_nombre_termino.Text))//Si no se pudo cambiar el nombre
                {
                    e.CancelEdit = true; //Cancela la edicion
                    MessageBox.Show("El nombre ya existe!"); //Informa
                }
            }
            else //Si es nuevo
            {
                textBox_jerarquia_nombre_termino.Text = e.Label;//Pone el nombre en el campo del nombre de termino
                textBox_jerarquia_descripcion_termino.Text = textBox_jerarquia_version_termino.Text = ""; //Limpia campos
                ComboBox_jerarquia_numero_nivel.SelectedIndex = -1;
                comboBox_jerarquia_lista_categoria_termino.SelectedIndex = -1;
                comboBox_jerarquia_lista_nivel_termino.SelectedIndex = -1;
                if (!agregarTermino())//Manda a agregar el termino si no se agrego entra al if
                {
                    MessageBox.Show("El nombre ya existe!"); //Informa
                    //e.CancelEdit = true; //Cancela la edicion
                    //e.Node.Text = "nuevo";
                    //e.Node.BeginEdit(); //Empieza la edicion de la etiqueta de nuevo
                    e.Node.Remove();//quita el nodo
                }
                //Limpia los campos
                textBox_jerarquia_nombre_termino.Text = textBox_jerarquia_descripcion_termino.Text = textBox_jerarquia_version_termino.Text = "";
                ComboBox_jerarquia_numero_nivel.SelectedIndex = -1;
                comboBox_jerarquia_lista_categoria_termino.SelectedIndex = -1;
                comboBox_jerarquia_lista_nivel_termino.SelectedIndex = -1;
            }
        }

        //Captura el evento del click en eliminar termino en click derecho del arbol
        private void eliminar_arbol_jerarquia_Click(object sender, EventArgs e)
        {
            //confirma el borrado
            DialogResult dr = MessageBox.Show("Está seguro que desea borrar el termino?",
                      "Borrar Termino", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            switch (dr)
            {
                case DialogResult.Yes: //en caso de que desee borrarlo
                    eliminarTermino();//manda a eliminar el termino
                    //Limpia los campos
                    textBox_jerarquia_nombre_termino.Text = textBox_jerarquia_descripcion_termino.Text = textBox_jerarquia_version_termino.Text = "";
                    ComboBox_jerarquia_numero_nivel.SelectedIndex = -1;
                    comboBox_jerarquia_lista_categoria_termino.SelectedIndex = -1;
                    comboBox_jerarquia_lista_nivel_termino.SelectedIndex = -1;
                    break;
                case DialogResult.No: break;
            }
        }

        //Captura el evento del click en mover como raiz de termino en click derecho del arbol
        public void moverComoRaiz_arbol_jerarquia_Click(object sender, EventArgs e)
        {
            TreeNode node = treeView_jerarquia.SelectedNode;
            String nombre = "";
            if (node.Parent != null)
            {
                nombre = node.Text;
                treeView_jerarquia.Nodes.Add((TreeNode)node.Clone());
                node.Parent.Nodes.Remove(node);
                moverTerminoComoRaiz(nombre);
            }
        }

        //Captura el evento del drag en el arbol de la jerarquia
        private void treeView_jerarquia_ItemDrag(object sender, ItemDragEventArgs e)
        {
            TreeView tree = (TreeView)sender;
            tree.DoDragDrop(e.Item, DragDropEffects.Move);
        }

        //Captura el evento de enter del drag en el arbol jerarquia
        private void treeView_jerarquia_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
        }

        //Captura el evento del drop en el arbol de la jerarquia
        private void treeView_jerarquia_DragDrop(object sender, DragEventArgs e)
        {
            Point loc = ((TreeView)sender).PointToClient(new Point(e.X, e.Y));
            TreeNode node = (TreeNode)e.Data.GetData(typeof(TreeNode));
            TreeNode destNode = ((TreeView)sender).GetNodeAt(loc);
            bool raices = false;
            bool posible = false;
            if (node != destNode && destNode != null)
            {
                TreeNodeCollection nodosRaices = ((TreeView)sender).Nodes;
                TreeNode raiz = nodosRaices[0];
                TreeNode hermanoRaiz = raiz.NextNode;
                if (hermanoRaiz != null) { raices = true; posible = true; }
                if (raices == false) { if (node.Parent != null) { posible = true; } }
                if (posible) //no se puede mover la raiz
                {
                    if (raices)
                    {
                        node.TreeView.Nodes.Remove(node); //si se trata de mover la raiz
                    }
                    else
                    {
                        node.Parent.Nodes.Remove(node);
                    }
                    destNode.Nodes.Add(node);
                    alteraOrdenTerminos(node.Text, destNode.Text);//Manda a alterar el orden
                }
            }
        }

        //Llena el arbol de una jerarquia
        public void llenarArbolJerarquia()
        {
            ArrayList NombreNodos = controlJerarquia.obtieneTerminosJerarquia(getCorrelativo()); //Guarda el nombre de los nodos
            ArrayList idNodos = new ArrayList();//Guarda el id de los nodos
            ArrayList idPadre = new ArrayList();//Guarda el id de los padre
            for (int i = 0; i < NombreNodos.Count; ++i)
            {
                idPadre.Add(controlJerarquia.obtenerAtributoTermino(NombreNodos[i].ToString(), "[id padre]", getCorrelativo()));
                idNodos.Add(controlJerarquia.obtenerAtributoTermino(NombreNodos[i].ToString(), "id", getCorrelativo()));
            }
            llenarArbol(NombreNodos, idNodos, idPadre);
        }

        //Concatena en una hilera los nombres de los nodos del arbol de una jerarquia 
        public string LlamadoRecursivo()
        {
            String miCadena = "";
            TreeNodeCollection nodes = treeView_jerarquia.Nodes;
            foreach (TreeNode n in nodes)
            {
                miCadena = ImprimeRecursivo(n, miCadena, 1);
            }
            return miCadena;
        }

        //Concatena de forma recursiva los nodos del arbol de una jerarquia 
        private String ImprimeRecursivo(TreeNode treeNode, string x, int y)
        {
            string espacios = "";
            for (int i = 0; i < y; ++i)
            {
                espacios = espacios + "\t";
            }
            x += espacios + "— " + treeNode.Text + "\n";
            int z = 0;
            foreach (TreeNode tn in treeNode.Nodes)
            {
                if (z == 0) { ++y; ++z; }
                x = ImprimeRecursivo(tn, x, y);
            }
            --y;
            return x;
        }

        //Quita las versiones de los termino
        public void deshabiliatarVersionTermino()
        {
            ControlJerarquia jer = new ControlJerarquia();
            jer.cambiarCampoAtributoDeTerminos(Nombre, "version", "NULL");//Pone en null el atributo de version de todos los terminos de la jerarquia
        }

        //Establece la categoria por defecto a una jerarquia con el nombre que recibe
        public void establecerCategoriaDefecto()
        {
            setListaPrincipalCategorias(categoriasDefecto);//Llena la lista de categorias
            controlJerarquia.cambiarCategoriasJerarquia(Nombre, categoriasDefecto);//Cambia las categorias de la jerarquia
            controlJerarquia.cambiarCampoAtributoDeTerminos(Nombre, "[id categoria]", "NULL");//Pone en null el atributo de id categoria de todos los terminos de la jerarquia
        }

        //Establece el nivel por defecto a una jerarquia con el nombre que recibe
        public void establecerNivelDefecto()
        {
            controlJerarquia.cambiarNivelesJerarquia(Nombre, nivelesDefecto);//Cambia los niveles de la jerarquia
            cambiarNivelesTerminosJerarquia(nivelesDefecto);//Manda a cambiar los niveles de los terminos
            setListaPrincipalNiveles(nivelesDefecto);//Llena la lista de niveles
        }

        //Manda a cambiar los niveles de los terminos de la jerarquia que recibe como parametro
        private void cambiarNivelesTerminosJerarquia(String listaNiveles)
        {
            foreach (TreeNode tn in  treeView_jerarquia.Nodes)//Recursivo para todas las raices
            {
                controlJerarquia.cambiarNivelDeTermino(Nombre, tn.Text, (tn.Level + 1).ToString(), listaNiveles);
                cambiarNivelesTerminosJerarquiaRecursivo(tn, listaNiveles);
            }
        }

        //Manda a cambiar los niveles de los terminos de la jerarquia de forma recursiva
        private void cambiarNivelesTerminosJerarquiaRecursivo(TreeNode nodo, String listaNiveles)
        {
            foreach (TreeNode tn in nodo.Nodes)//Recursivo para todos los nodos
            {
                controlJerarquia.cambiarNivelDeTermino(Nombre, tn.Text, (tn.Level + 1).ToString(), listaNiveles);
                cambiarNivelesTerminosJerarquiaRecursivo(tn, listaNiveles);
            }
        }

        //Quita los atributos de categoria de una jerarquia con el nombre que recibe
        public void quitarCategoriasJerarquia()
        {
            controlJerarquia.cambiarCategoriasJerarquia(Nombre,"NULL");//Pone en null la categoria de la jerarquia
            //jer.cambiarCampoAtributoDeTerminos(nombreJerarquia, "[id categoria]", "NULL");//Pone en null el atributo de id categoria de todos los terminos de la jerarquia
        }

        //Quita los atributos de niveles de una jerarquia con el nombre que recibe
        public void quitarNivelesJerarquia()
        {
            controlJerarquia.cambiarNivelesJerarquia(Nombre, "NULL");//Pone en null el nivel de la jerarquia
        }

        //Cambia las categorias de una jerarquia, recibe nombre de la jerarquia
        public void llenarListaCategoriasDeTermino()
        {
            String nombreCategoriaActual = controlJerarquia.obtenerCategoriaJerarquia(Nombre);
            if (nombreCategoriaActual != getListaPrincipalCategorias())//Si se eligio una diferente
            {
                controlJerarquia.cambiarCategoriasJerarquia(Nombre,getListaPrincipalCategorias());//cambia la categoria de la jerarquia
                LimpiarListaCategoriasTermino();//limpia la lista desplegable
                llenarListaCategoriasTermino(controlJerarquia.obtenerListaCategoriasDeTerminos(Nombre));//Llena la lista con las nuevas categorias
                controlJerarquia.cambiarCampoAtributoDeTerminos(Nombre, "[id categoria]", "NULL");//Pone en null el atributo de id categoria de todos los terminos de la jerarquia
            }
        }

        //Cambia los niveles de una jerarquia, recibe nombre de la jerarquia
        public void llenarListaNivelesDeTermino()
        {
            String nombreNivelActual = controlJerarquia.obtenerNivelJerarquia(Nombre);
            if (nombreNivelActual != getListaPrincipalNiveles())//Si se eligio una diferente
            {
                controlJerarquia.eliminarNivelesCategorias(getCorrelativo());
                controlJerarquia.cambiarNivelesJerarquia(Nombre, getListaPrincipalNiveles());//cambia la categoria de la jerarquia
                LimpiarListaNivelesTermino();//limpia la lista desplegable
                llenarListaNivelesTermino(controlJerarquia.obtenerListaNivelesDeTerminos(Nombre));//Llena la lista con los nuevos niveles
                cambiarNivelesTerminosJerarquia(getListaPrincipalCategorias());
            }
        }

        //Carga los datos de un termino en la interfaz
        public void cargarTermino(String nombreTermino)
        {
            //Limpia los campos
            setNombreTermino("");
            setDescripcionTermino("");
            setVersionTermino("");
            setListaCategoriaTermino(-1);
            setListaNivelTermino(-1);
            setNumeroNivel(-1);
            setRutaRaiz("");
            habilitacionBotonAgregarTermino(false);
            habilitacionBotonElimiarTermino(true);
            habilitacionBotonModificarTermino(true);
            //Carga los datos del termino
            setNombreTermino(controlJerarquia.obtenerAtributoTermino(nombreTermino, "nombre", getCorrelativo()));
            setDescripcionTermino(controlJerarquia.obtenerAtributoTermino(nombreTermino, "descripcion", getCorrelativo()));
            setRutaRaiz(rutaTermino(getArbolJerarquico().SelectedNode));
            if (getConVersion())//Si tiene version
            {
                setVersionTermino(controlJerarquia.obtenerAtributoTermino(nombreTermino, "version", getCorrelativo()));
            }
            if (getConCategorias())//Si tiene categoria
            {
                setListaCategoriaTermino(controlJerarquia.obtenerCategoriaTermino(nombreTermino, getCorrelativo()));
            }
            if (getConNiveles())//Si tiene nivel
            {
                setNumeroNivel((getArbolJerarquico().SelectedNode.Level + 1).ToString());
                setListaNivelTermino(controlJerarquia.obtenerNivelTermino(nombreTermino, getCorrelativo()));
            }
            /* 
         if (nivel != "" && conNivel.Checked)
         {
             SqlDataReader datos1;
             sentenciaSql = "SELECT T.[nombre], N.[numero nivel] FROM [GIFT].[dbo].[termino_lista] T, [GIFT].[dbo].[nivel] N WHERE T.[id] in ( SELECT M.[id termino lista] FROM [GIFT].[dbo].[nivel] M WHERE N.id = M.id and M.[id] = " + nivel + ")";
             datos1 = Principal.HacerConsulta(sentenciaSql);
             datos1.Read();
             if (datos1.HasRows)
             {
                 nivelTermino.Text = datos1.GetValue(0).ToString();
                 numeroNivel.Text = datos1.GetValue(1).ToString();
                 Principal.GetConexion().Close();//Cierra la conexion
             }
             else
             {
                 Principal.GetConexion().Close();//Cierra la conexion
                 numeroNivel.Text = (nodo.Level + 1).ToString();
             }
         }
             */
        }

        //Recibe un nodo y busca su ruta hasta la raiz
        private String rutaTermino(TreeNode nodoSelec)
        {
            String ruta = "";
            while (nodoSelec.Parent != null)
            {
                ruta = " >> " + nodoSelec.Text + ruta;
                nodoSelec = nodoSelec.Parent;
            }
            ruta = " >> " + nodoSelec.Text + ruta;
            return ruta;
        }

        //Busca un termino en el arbol de terminos de un jerarquia
        public void buscarTermino()
        {
            String terminoABuscar = controlJerarquia.buscarContenidoEnTermino(getBuscarTermino(), getCorrelativo());
            if (terminoABuscar != "")
            {
                foreach (TreeNode tn in treeView_jerarquia.Nodes)
                {
                    if (tn.Text == terminoABuscar)
                    {
                        treeView_jerarquia.SelectedNode = tn;
                        tn.EnsureVisible();
                        cargarTermino(treeView_jerarquia.SelectedNode.Text);
                    }
                    else
                    {
                        ubicar_termino_recursivamente(tn, terminoABuscar);
                    }
                }
            }
            else
            {
                MessageBox.Show("No se encontro ningun resultado para su busqueda");
            }
            setBuscarTermino("");
        }

        //Busca de manera recursiva el nodo 
        private void ubicar_termino_recursivamente(TreeNode treeNode, String terminoABuscar)
        {
            foreach (TreeNode tn in treeNode.Nodes)
            {
                if (tn.Text == terminoABuscar)
                {
                    treeView_jerarquia.SelectedNode = tn;
                    tn.EnsureVisible();
                    cargarTermino(treeView_jerarquia.SelectedNode.Text);
                }
                else
                {
                    ubicar_termino_recursivamente(tn, terminoABuscar);
                }
            }
        }

        //Modifica los datos de un termino de la jerarquia
        public void modificarTermino()
        {
            String categoria = "NULL", version = "NULL";
            if (getConVersion())//Si tiene version
            {
                version = getVersionTermino();
            }
            if (getConCategorias())//Si tiene categorias
            {
                categoria = controlJerarquia.buscarIdTerminoListaPorNombre(getListaCategoriaTermino(), getListaPrincipalCategorias());
            }
            controlJerarquia.modificarTermino(getNombreTermino(), getDescripcionTermino(), categoria, version, getCorrelativo());
        }

        //Agrega un termino a la jerarquia, retorna un 1 si fue exitoso
        public bool agregarTermino()
        {
            if (!controlJerarquia.existeTermino(getNombreTermino(),Nombre))//Si el nombre no existe
            {
                TreeNode padre = treeView_jerarquia.SelectedNode; //Busca al padre 
                //Va a agregar al treeView
                TreeNode tnode = new TreeNode(getNombreTermino());
                tnode.ContextMenuStrip = contextMenuStrip_clickDerecho_arbol_jerarquia; //Agrega el menuStrip para el click derecho
                if (padre == null)//si es nodo raiz
                {
                    treeView_jerarquia.Nodes.Add(tnode);
                }
                else //Si no es raiz
                {
                    padre.Nodes.Add(tnode);
                }
                String idPadre = "NULL", idCategoria = "NULL", version = "NULL", idNivel = "NULL";
                if (padre != null)//Si tiene padre
                {
                    idPadre = controlJerarquia.obtenerAtributoTermino(padre.Text, "id", getCorrelativo());//Guarda el padre
                }
                if (getConCategorias() && getListaCategoriaTermino() != "")//Si tiene categoria
                {
                    idCategoria = controlJerarquia.buscarIdTerminoListaPorNombre(getListaCategoriaTermino(), getListaPrincipalCategorias());//Guarda la categoria
                }
                if (getConVersion() && getVersionTermino() != "")//Si tiene version
                {
                    version = getVersionTermino();//Guarda la version
                }
                controlJerarquia.crearNuevoTermino(getNombreTermino(), getDescripcionTermino(), idCategoria, idNivel, idPadre, version, getCorrelativo());
                int numTer = controlJerarquia.modificarNumeroTerminos(Nombre, 1); //Modifica el numero de terminos
                setNumTerminos(numTer.ToString());
                if (getConNiveles()) //Si tiene niveles
                {
                    //Operaciones con los niveles
                }
                CuentaNiveles();
                return true;//anuncia que fue exitoso
            }
            return false; //si llega aqui es que no se pudo hacer
        }

        //Elimina un termino de la jerarquia
        public void eliminarTermino()
        {
            if (getArbolJerarquico().SelectedNode.Nodes.Count > 0)//si tiene hijos
            {
                String idTermino = controlJerarquia.obtenerAtributoTermino(getNombreTermino(), "id", getCorrelativo());//Saca el id del termino
                String idPadreTermino = controlJerarquia.obtenerAtributoTermino(getNombreTermino(), "[id padre]", getCorrelativo());//Saca el id del padre del termino
                if (idPadreTermino == "")//si es la raiz
                {
                    idPadreTermino = "NULL";
                }
                controlJerarquia.cambiarPadreDeHijos(idTermino, idPadreTermino, getCorrelativo());//Cambia los padres de los hijos
            }
            //cambiarNiveles(jerarquia.getArbolJerarquico().SelectedNode, jerarquia.getCorrelativo()); //manda a arreglar los niveles de los terminos
            controlJerarquia.borrarTermino(getNombreTermino(), getCorrelativo());//Elimina el termino
            int numTerminos = controlJerarquia.modificarNumeroTerminos(getNombre(), -1); //Disminuye la cantidad de terminos 
            setNumTerminos(numTerminos.ToString());//Lo muestra en la pestana
            //Vuelve a llenar el arbol
            getArbolJerarquico().Nodes.Clear();
            llenarArbolJerarquia();
            getArbolJerarquico().ExpandAll();
            //FALTA OPERACION DE NIVELES
            CuentaNiveles();
        }

        //Arregla los niveles de los terminos al ser eliminado un nodo
        private void cambiarNiveles(TreeNode nodoTermino)
        {
            //String idPadre, idNivelPadre;
            if (nodoTermino != null)
            {
                foreach (TreeNode tn in nodoTermino.Nodes)
                {/*
                    //Busca el id y el nivel del padre
                    sentenciaSql = "SELECT [id], [id nivel] FROM [GIFT].[dbo].[termino] WHERE nombre = '" + nodoTermino.Text + "' and [correlativo jerarquia] = " + correlativo;
                    datos = Principal.HacerConsulta(sentenciaSql);
                    datos.Read();
                    idPadre = datos.GetValue(0).ToString();
                    idNivelPadre = datos.GetValue(1).ToString();
                    Principal.GetConexion().Close();//Cierra la conexion
                    cambiarNiveles(tn, correlativo); //Llama recursivamente a corregir a sus hijos
                    //Cambia el nivel de los hijos
                    sentenciaSql = "UPDATE [GIFT].[dbo].[termino] SET [id nivel] = " + idNivelPadre + " WHERE nombre = '" + tn.Text + "' and [correlativo jerarquia] = " + correlativo;
                    datos = Principal.HacerConsulta(sentenciaSql);
                    Principal.GetConexion().Close();//Cierra la conexion
                  * */
                }
            }
        }

        //Edita el nombre de un termino
        public bool editarNombreTermino(String nombreNuevo, String nombreActual)
        {
            if (!controlJerarquia.existeTermino(nombreNuevo,Nombre))//Si el nombre ya existe
            {
                controlJerarquia.modificarAtributoTermino(nombreActual, "nombre", "'" + nombreNuevo + "'", getCorrelativo());//Modifica el nombre
                return true; //anuncia el exito
            }
            return false; //avisa el fracaso de la operacion
        }

        //Cambia el arbol de la jerarquia al hacer el drag and drop de un termino
        public void alteraOrdenTerminos(String termino, String terminoDestino)
        {
            String idTerminoDestino = controlJerarquia.obtenerAtributoTermino(terminoDestino, "id", getCorrelativo());
            controlJerarquia.modificarAtributoTermino(termino, "[id padre]", idTerminoDestino, getCorrelativo());
            //CAMBIA LOS NIVELES
            CuentaNiveles();
        }

        //Mueve un termino como raiz 
        public void moverTerminoComoRaiz(String nombreTermino)
        {
            String idTermino = controlJerarquia.obtenerAtributoTermino(nombreTermino, "id", getCorrelativo());
            controlJerarquia.modificarAtributoTermino(nombreTermino, "[id padre]", "NULL", getCorrelativo());
            //CAMBIA LOS NIVELES
            CuentaNiveles();
        }

        int cant;
        //Cuenta los niveles de una jerarquia
        private void CuentaNiveles()
        {
            cant = 0;
            int cantNiveles = 0;
            TreeNodeCollection nodes = treeView_jerarquia.Nodes;
            foreach (TreeNode n in nodes)
            {
                cantNiveles = CuentaNivelesRecursivo(n, 1);
            }
            if (nodes.Count >= 1)
            {
                cantNiveles = cant + 1;
            }
            int nivAnterior = controlJerarquia.obtenerNumeroNiveles(Nombre); //Obtiene la cantidad de niveles que tenia
            int diferencia = (nivAnterior - cantNiveles) * -1;
            cantNiveles = controlJerarquia.modificarNumeroNiveles(Nombre, diferencia);
            setNumNiveles(cantNiveles.ToString());
            LimpiarNumeroNiveles();
            llenarNumeroNiveles(cantNiveles);
        }

        //Cuenta los niveles de una jerarquia recursivamente
        private int CuentaNivelesRecursivo(TreeNode treeNode, int y)
        {
            foreach (TreeNode tn in treeNode.Nodes)
            {
                ++y;
                y = CuentaNivelesRecursivo(tn, y);
                if (cant < y) { cant = y; }
            }
            --y;
            return y;
        }


        //Captura el click en el boton cerrar de una pestana
        private void botonCerrar_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        //Captura el click en el boton borrar de una pestana
        private void botonEliminar_Click(object sender, EventArgs e)
        {
            borrarArchivo();
        }

        //Captura el click en el boton guardar de una pestana
        private void botonGuardar_Click(object sender, EventArgs e)
        {
            guardarArchivo();//manda a guardar el archivo
        }

        //Captura el click en el boton guardarComo de una pestana
        private void botonGuardarComo_Click(object sender, EventArgs e)
        {
            hacerCopia();
        }

        //Se da cuenta cuando se hicieron cambios
        private void seHicieronCambios(object sender, EventArgs e)
        {
            if (Principal.estaAbierta(Nombre))
            {
                this.modificado = true;
                botonGuardarJerarquia.Enabled = true;
            }
        }

        //Se da cuenta cuando se hicieron cambios
        public void seHicieronCambios(object sender, System.Windows.Forms.KeyPressEventArgs e)
        {
            this.modificado = true;
            botonGuardarJerarquia.Enabled = true;
        }


        //Captura el evento que suceda antes de cerrar la ventana
        private void click_cerrarVentana(object sender, FormClosingEventArgs e)
        {
            if (modificado)
            {
                guardarArchivo();
            }
            Principal.ventanaEnfocada(null, ""); //Manda a quitarse como la enfocada
        }

        //Manda a guardar un archivo
        public void guardarArchivo()
        {
            //confirma el guardado
            DialogResult dr = MessageBox.Show("Desea guardar los cambios de " + Nombre + "?", "Guardar", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            switch (dr)
            {
                case DialogResult.Yes: //en caso de que desee guardar
                    //manda a modificar la jerarquia
                    controlJerarquia.modificarJerarquia(getNombre(), getDescripcion(), getNumTerminos(), getNumNiveles(), getConCategorias(), getConNiveles(), getConVersion(), false, getNombrePorNivel());
                    Principal.habilitacionCampos();
                    this.modificado = false;
                    this.botonGuardarJerarquia.Enabled = false; 
                    break;
                case DialogResult.No: break;
            }
        }

        //Manda a hacer una copia del numero
        public void hacerCopia()
        {
            GuardarComo guardar = new GuardarComo(Principal, "jerarquia", this);
            guardar.Show();
        }

        //Manda a borrar el archivo
        public void borrarArchivo()
        {
            //confirma el borrado
            DialogResult dr = MessageBox.Show("Está seguro que desea borrar la jerarquia?", "Borrar jerarquia", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            switch (dr)
            {
                case DialogResult.Yes: //en caso de que desee borrarlo
                    controlJerarquia.borrarJerarquia(Nombre);
                    Principal.habilitacionCampos();
                    Principal.GetControlInterfaz().quitarNodo(Principal.GetTreeView(), Nombre, "jerarquia");
                    this.Close();
                    break;
                case DialogResult.No: break;
            }
        }

        //Captura el evento de cuando la ventana es enfocada
        private void VentanaEnfocada(object sender, EventArgs e)
        {
            Principal.ventanaEnfocada(this, "jerarquia"); //Manda a ponerse como la enfocada
        }

        //Captura el evento de cuando la ventana es desenfocada
        private void VentanaDesenfocada(object sender, EventArgs e)
        {
            Principal.ventanaEnfocada(null, ""); //Manda a quitarse como la enfocada
        }


    }//Fin de la clase
}
